package com.rx.mgt.dao.base;

import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

@SuppressWarnings("unchecked")
public class ManagementHibernateDaoBase<T, I extends Serializable> {
    protected Class<T> entityClass;
    @Autowired
    @Qualifier("managmentHibernateTemplate")
    protected HibernateTemplate template;

    public ManagementHibernateDaoBase() {
    }

    protected Class getEntityClass() {
        if (entityClass == null) {
            entityClass = (Class<T>) ((ParameterizedType) getClass()
                    .getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return entityClass;
    }

    public void saveOrUpdate(T t) throws DataAccessException {
        template.saveOrUpdate(t);
    }

    public T load(I id) throws DataAccessException {
        return (T) template.load(getEntityClass(), id);
    }

    public T get(I id) throws DataAccessException {
        return (T) template.get(getEntityClass(), id);
    }

    public T getById(String id) throws DataAccessException {
        return (T) template.get(getEntityClass(), id);
    }

    public boolean contains(T t) throws DataAccessException {
        return template.contains(t);
    }

    public void delete(T t, LockMode lockMode) throws DataAccessException {
        template.delete(t, lockMode);
    }

    public void delete(T t) throws DataAccessException {
        template.delete(t);
    }

    public void deleteAll(Collection<T> entities) throws DataAccessException {
        template.deleteAll(entities);
    }

    public List<T> find(String queryString, Object value) throws DataAccessException {
        return (List<T>) template.find(queryString, value);
    }

    public List<T> find(String queryString, Object[] values) throws DataAccessException {
        return (List<T>) template.find(queryString, values);
    }

    public List<T> find(String queryString) throws DataAccessException {
        return (List<T>) template.find(queryString);
    }

    public void refresh(T t, LockMode lockMode) throws DataAccessException {
        template.refresh(t, lockMode);
    }

    public void refresh(T t) throws DataAccessException {
        template.refresh(t);
    }

    public Serializable save(T t) throws DataAccessException {
        return template.save(t);
    }

    public void saveOrUpdateAll(Collection<T> entities)
            throws DataAccessException {
        template.saveOrUpdateAll(entities);
    }

    public void update(T t, LockMode lockMode) throws DataAccessException {
        template.update(t, lockMode);
    }

    public void update(T t) throws DataAccessException {
        template.update(t);
    }

    public List<T> list() throws DataAccessException {
        return template.loadAll(getEntityClass());
    }

    public List<T> findByNamedQuery(String queryName)
            throws DataAccessException {
        return template.findByNamedQuery(queryName);
    }

    public List<T> findByNamedQuery(String queryName, Object value)
            throws DataAccessException {
        return template.findByNamedQuery(queryName, value);
    }

    public List<T> findByNamedQuery(String queryName, Object[] values)
            throws DataAccessException {
        return template.findByNamedQuery(queryName, values);
    }

    public HibernateTemplate getTemplate() {
        return template;
    }

    public void setTemplate(HibernateTemplate template) {
        this.template = template;
    }

    public void persist(final T app) {
        template.execute(new HibernateCallback<T>() {
            public T doInHibernate(Session session) throws HibernateException, SQLException {
                session.persist(app);
                return null;
            }
        });
    }


}
